﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Axe
{
    public interface ITimeExpirationLock
    {
        TimeSpan ExpirationTime { get; set; }
        DateTime ExpireDate { get; }
        bool IsExpired(DateTime untilTime);
        DateTime TimeStart { get; set; }
        void Renew();
    }

    public class TimeExpirationLock : ITimeExpirationLock
    {
        DateTime m_TimeStart;
        TimeSpan m_ExpirationInterval;

        #region public DateTime TimeStart
        public DateTime TimeStart
        {
            get { return m_TimeStart; }
            set { m_TimeStart = value; }
        }  
        #endregion      

        #region public TimeSpan ExpirationTime
        public TimeSpan ExpirationTime
        {
            get { return m_ExpirationInterval; }
            set { m_ExpirationInterval = value; }
        } 
        #endregion

        #region public DateTime ExpireDate
        public DateTime ExpireDate
        {
            get
            {
                return m_TimeStart + m_ExpirationInterval;
            }
        } 
        #endregion

        #region public bool IsExpired(DateTime untilTime)
        public bool IsExpired(DateTime untilTime)
        {
            TimeSpan elapsedSpan = untilTime - m_TimeStart;
            return elapsedSpan >= m_ExpirationInterval;
        } 
        #endregion

        #region public void Renew()
        public void Renew()
        {
            m_TimeStart = DateTime.Now;
        } 
        #endregion

        public TimeExpirationLock()
        {

        }

        public TimeExpirationLock(TimeSpan span)
        {
            m_TimeStart = DateTime.Now;
            m_ExpirationInterval = span;
        }

        public TimeExpirationLock(DateTime starTime,TimeSpan span)
        {
            m_TimeStart = starTime;
            m_ExpirationInterval = span;
        }

        #region public static IEnumerable<TimeExpirationLock> GetActiveLocks(IEnumerable<TimeExpirationLock> locks, DateTime untilTime)
        public static IEnumerable<ITimeExpirationLock> GetActiveLocks(IEnumerable<ITimeExpirationLock> locks, DateTime untilTime)
        {
            foreach (ITimeExpirationLock expirationLock in locks)
            {
                if (!expirationLock.IsExpired(untilTime))
                {
                    yield return expirationLock;
                }
            }
        } 
        #endregion

        #region public static bool IsExpired(IEnumerable<TimeExpirationLock> locks, DateTime untilTime)
        public static bool IsExpired(IEnumerable<ITimeExpirationLock> locks, DateTime untilTime)
        {
            foreach (ITimeExpirationLock exLock in locks)
            {
                if (exLock.IsExpired(untilTime) == false)
                    return false;
            }

            return true;
        } 
        #endregion
    }
}
